﻿using System;
using System.Collections.Generic;
using System.Text;

namespace _015_使用泛型和索引器来实现一个我们自己的集合类MyList
{
                        //表示这个类型是继承至这个接口的，这是一个可比较的接口
    class MyList<T> where T:IComparable
    {
        private T[] array;
        private int count;//表示添加当前元素的个数

        //有参传进来就设置数组大小
        public MyList(int size)
        {
            if (size>=0)
            {
                array = new T[size];
            }
        }
        //无参传进来
        public MyList()
        {
            array = new T[0];
        }
        /// <summary>
        /// 获取数组长度
        /// </summary>
        public int Capacity
        {
            get
            {
                return array.Length;
            }
        }
        /// <summary>
        /// 获取当前元素个数
        /// </summary>
        public int Count {
            get { return count; } 
        }

        public void Add(T item)
        {
            if (Count==Capacity)//判断元素个数跟列表容量大小是否一样大，如果一样大，说明数组容量不够用，需要创建新的数组
            {
                if (Capacity == 0)
                {
                    array = new T[4];//当数组长度为0的时候，创建一个长度为4的新数组 
                }
                else
                {
                    var newArray = new T[Capacity * 2];//当数组长度不为0的时候，创建当前长度翻倍的新数组 
                    Array.Copy(array, newArray,count);//把旧数组中的元素复制到新的数组中，复制前count个 array-->newArray
                    array = newArray;//最后再把新数组替换掉旧数组，然后旧数组的数据就会被回收掉
                }
            }
            //经过上面的判断语句，我们的数组容量就不会满了，就可以添加元素了
            array[Count] = item;//增加新元素
            count++;//元素个数自增
        }


        //利用下标去查找元素
        public T GetItem(int index)
        {
            if (index >= 0 && index <= count-1)
            {
                return array[index];
            }
            else
            {
                throw new Exception("索引超出了范围");
            }
        }

        //索引器：通过[index]这种形式去访问数据，就是索引器
        public T this[int index]
        {
            get//当我们通过索引器取值的时候，会调用get块
            {
               return GetItem(index);
            }
            set//当我们通过索引器取值的时候，会调用set块
            {
                //要符合规则
                if (index >= 0 && index <= count - 1)
                {
                    array[index] = value;
                }
                else
                {
                    throw new Exception("索引超出了范围");
                }
            }
        }
        //实现列表的插入方法
        public void Insert(int index,T item)
        {
            if (index >= 0 && index <=count-1)
            {
                if (Count==Capacity)//如果容量不够
                {
                    var newArray = new T[Capacity * 2];
                    Array.Copy(array, newArray, count);
                    array = newArray;
                }
                //把插入的位置及后面的元素，往后移动一个单位
                for (int i = Count-1; i >=index; i--)
                {
                    array[i + 1] = array[i];
                }
                //可以插入数据了
                array[index] = item;
                count++;//元素个数自增
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }
        /// 删除对应索引的元素
        public void RemoveAt(int index)
        {
            if (index >= 0 && index <= count - 1)
            {
                //把删除的元素后面的元素，往前移动一个单位
                for (int i = index+1; i <= Count-1; i++)
                {
                    array[i-1] = array[i];
                }
                count--;//元素个数自减
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }
        //从前往后匹配
        public int IndexOf(T item)
        {
            for (int i = 0; i < count; i++)
            {
                if (array[i].Equals(item))
                {
                    return i;
                }

            }
            return -1;
        }
        //从后往前匹配
        public int LastIndexOf(T item)
        {
            for (int i = Count-1; i >=0; i--)
            {
                if (array[i].Equals(item))
                {
                    return i;
                }

            }
            return -1;
        }

        /// <summary>
        /// 排序
        /// </summary>
        public void Sort()
        {
            for (int j = 0; j < Count - 1; j++)
            {
                for (int i = 0; i < Count - 1-j; i++)
                {
                                //一个继承自某个接口泛型比较的方法
                    if (array[i].CompareTo(array[i + 1]) > 0)
                    {
                        T temp = array[i];
                        array[i] = array[i + 1];
                        array[i + 1] = temp;
                    }
                }
            }
        }
    }
}
